import { getMenuListApi } from "@/api/menu/menu";
// 路由的类型声明
import { RouteRecordRaw } from "vue-router";
import { ActionContext } from "vuex";
import { RootState } from "..";
import Layout from '@/layout/Index.vue'
// 加载views文件夹下面的所有的vue文件
const modules = import.meta.glob('../../views/**/*.vue')
// 定义state
export type MenuState = {
  count: number,
  collapse: boolean,
  menuList: any
}

export const state: MenuState = {
  count: 0,
  collapse: false,
  menuList: [
    {
      path: '/dashboard',
      component: "Layout",
      meta: {
        title: "首页",
        icon: "HomeFilled",
        roles: ["sys:manage"]
      },
      children: []
    }
  ]
}

// 定义mutations
export const mutations = {
  setCount(state: MenuState, count: number) {
    state.count = count;
  },
  //设置collapse
  setCollapse: (state: MenuState, collapse: boolean) => {
    state.collapse = collapse;
  },
  setMenuList: (state: MenuState, routes: Array<RouteRecordRaw>) => {
    state.menuList = state.menuList.concat(routes)
  }
}

// 定义actions
export const actions = {
  // 这个方法的调用是在main.ts中的59行附近的路由守卫中调用的，
  // 是在获取了用户信息之后，调用的获取路由列表的接口
  // 这时已经把整个的router作为第二个参数传递过来了
  //  await store.dispatch('menu/getMenuList', router)
  getMenuList({ commit }: ActionContext<MenuState, RootState>, router: any) {
    return new Promise((resolve, reject) => {
      getMenuListApi().then(res => {
        let accessedRoutes
        if (res.code === 200) {
          // 动态生成路由
          accessedRoutes = filterAsyncRoutes(res.data, router);
          // console.log('打印这里擦混入的参数',router);
          // 这里传入的router是整个的router对象
          // 设置MenuList，把新获取的数据和原有的数据一同相加
          commit('setMenuList', accessedRoutes)
        }
        resolve(accessedRoutes)
      }).catch(error => {
        reject(error)
      })
    })
  }
}

export function filterAsyncRoutes(routes: RouteRecordRaw[], router: any) {
  // 目标的数组，是一个路由的集合
  const res: Array<RouteRecordRaw> = []
  // 这个是后台返回的路由列表，已经处理过的
  routes.forEach((route: any) => {
    // 深复制一下
    const tmp = { ...route }
    const component = tmp.component
    // 这里先使用route（原始数据）来判断有没有组件
    if (route.component) {
      // 然后判断如果又组建，名称为Layout
      if (component === 'Layout') {
        tmp.component = Layout
      } else {
        // 在组件名称不是layout的时候，就需要引入不同的组件
        // 这里就使用到了这个根据不同的组件名称,引入对应的组件
        // 跟webpack的写法有一些区别
        tmp.component = modules[`../../views${component}.vue`]
      }
    }
    // 如果有children属性,就进行递归
    if (tmp.children) {
      tmp.children = filterAsyncRoutes(tmp.children, router)
    }
    // 这里传入router的目的就是为了调用addRoute()这个方法来添加路由
    // 如果不添加这个方法，数据是可以缓存，但是路由都没了，点击路由，地址会跳转
    // 但是具体的路由页面，都找不到了
    router.addRoute(tmp)
    res.push(tmp)
  })
  return res
}

export const getters = {
  getCount(state: MenuState) {
    return state.count
  },
  getCollapse: (state: MenuState) => {
    return state.collapse;
  },
  getMenuList:(state: MenuState)=>{
    return state.menuList
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}